class Watcher {
    constructor(vm, expr, cb) {
        this.vm = vm;
        this.expr = expr;
        this.cb = cb;
        // 先把旧值保存起来
        this.oldVal = this.getOldVal();
    }
    getOldVal() {
        Dep.target = this;
        const oldVal = compileUtil.getVal(this.expr, this.vm);
        Dep.target = null;
        return oldVal;
    }
    update() {
        const newVal = compileUtil.getVal(this.expr, this.vm);
        if (newVal !== this.oldVal) {
            this.cb(newVal);
        }
    }
}
class Dep {
    constructor() {
        this.subs = [];
    }
    //收集观察者
    addSub(watcher) {
        this.subs.push(watcher);
    }
    //通知观察者去更新
    notify() {
        console.log('通知了观察者', this.subs);
        this.subs.forEach((w) => {
            console.log('notify subs ', w);
            w.update();
        });
    }
}
class Observer {
    constructor(data) {
        this.observe(data);
    }
    observe(data) {
        if (data && typeof data === 'object') {
            Object.keys(data).forEach((key) => {
                this.defineReactive(data, key, data[key]);
            });
        }
    }
    defineReactive(obj, key, value) {
        //递归遍历
        this.observe(value);
        const dep = new Dep();
        Object.defineProperty(obj, key, {
            //对象属性是否可通过for-in循环，flase为不可循环，默认值为true
            enumerable: true,
            //能否使用delete、能否需改属性特性、或能否修改访问器属性、，false为不可重新定义，默认值为true
            configurable: false,
            get() {
                //订阅数据变化时，往Dep添加watchers
                Dep.target && dep.addSub(Dep.target);
                return value;
            },
            set: (newVal) => {
                this.observe(newVal);
                if (newVal !== value) {
                    value = newVal;
                }
                //通知Dep变化
                dep.notify();
            },
        });
    }
}
